package edu.gatech.cs2340.thecyclonesquad.models;


import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import edu.gatech.cs2340.thecyclonesquad.models.Person;

public class InMemoryModel {
	/** the data store of all people */
	private static Map<String, Person> people = new HashMap<String, Person>();
	
	/** the data store of all items */
	private static Map<String, Item> items = new HashMap<String, Item>();
	
	//Initialize an administrator
	static {
		Person a = new Person("admin" , "admin");
		a.admin = true;
		people.put(a.username, a);
	}
	
	public static String currentUser;
	
	/**
	 * Adds the person to the system
	 * @param p is a person object which is a new user that will be registered to the application
	 */
	public void addPerson(Person p) {
		people.put(p.username, p);
	}
	
	/**
	 * Finds person in database and returns the person if found.
	 * @param username is the string of the username of an user's account that we want to find
	 * @return a person object with the same username as the username in the parameter
	 */
	public Person findPerson(String username) {
		Person p = people.get(username);
		if (p == null) {
			return Person.NULL_PERSON;
		} else {
			return p;
		}
	}
	
	/**
	 * Removes a person from system
	 * @param username is the string of the username of an user who is going to have his/her account deleted
	 */
	public void removePerson(String username) {
		people.remove(username);		
	}
	
	/**
	 * Get all the locked users.
	 * @return a string array of the usernames of all the locked users
	 */
	public String[] getLockedUsers() {
		//Making a copy of data to pass over trust boundary
		Collection<Person> p = people.values();
		int size = 0;
		for (Person p1: p) {
			if (p1.locked == true) {
				size++;
			}
		}
		String[] retVal = new String[size];
		int x = 0;
		for (Person p1 : p) {
			if (p1.locked == true) {
				retVal[x++] = p1.username;
			}
		}
		return retVal;
	}
	
	/**
	 * Add item to the database. 
	 * @param i is an item object that we want to add to the list of all lost items
	 */
	public void addItem(Item i) {
		items.put(i.name, i);
	}
	
	
	/**
	 * Get all the lost item names of a user.
	 * @return the names of all the lost items of a specific user
	 */
	public String[] getLostItemNames() {
		//Making a copy of data to pass over trust boundary
		Collection<Item> i = items.values();
		int size = 0;
		for (Item i1 : i) {
			if ((i1.owner.equals(InMemoryModel.currentUser)) && (i1.type.equals("Lost"))) {
				size++;
			}
		}
		String[] retVal = new String[size];
		int x = 0;
		for (Item i1 : i) {
			if ((i1.owner.equals(InMemoryModel.currentUser)) && (i1.type.equals("Lost"))) {
				retVal[x++] = i1.name;
			}
		}
		return retVal;
	}
	
	/**
	 * Get all the found item names of the user
	 * @return a string array of all the found item names
	 */
	public String[] getFoundItemNames() {
		//Making a copy of data to pass over trust boundary
		Collection<Item> i = items.values();
		int size = 0;
		for (Item i1 : i) {
			if ((i1.owner.equals(InMemoryModel.currentUser)) && (i1.type.equals("Found"))) {
				size++;
			}
		}
		String[] retVal = new String[size];
		int x = 0;
		for (Item i1 : i) {
			if ((i1.owner.equals(InMemoryModel.currentUser)) && (i1.type.equals("Found"))) {
				retVal[x++] = i1.name;
			}
		}
		return retVal;
	}
	
	/**
	 * Filters a list by category.
	 * @param type1 is if lost or found
	 * @param category1 is which category we want to filter
	 * @return names of all the filtered items
	 */
	public String[] filterByCategory(String type1, String category1) {
		//Making a copy of data to pass over trust boundary
				Collection<Item> i = items.values();
				int size = 0;
				for (Item i1 : i) {
					if ((i1.owner.equals(InMemoryModel.currentUser)) && (i1.type.equals(type1)) && (i1.category.equals(category1))) {
						size++;
					}
				}
				String[] retVal = new String[size];
				int x = 0;
				for (Item i1 : i) {
					if ((i1.owner.equals(InMemoryModel.currentUser)) && (i1.type.equals(type1)) && (i1.category.equals(category1))) {
						retVal[x++] = i1.name;
					}
				}
				return retVal;
	}
	
	/**
	 * Filters a list by status.
	 * @param type1 is if lost or found
	 * @param status1 is which status we want to filter
	 * @return names of all the filtered items
	 */
	public String[] filterByStatus(String type1, boolean status1) {
		//Making a copy of data to pass over trust boundary
				Collection<Item> i = items.values();
				int size = 0;
				for (Item i1 : i) {
					if ((i1.owner.equals(InMemoryModel.currentUser)) && (i1.type.equals(type1)) && (i1.status == status1)) {
						size++;
					}
				}
				String[] retVal = new String[size];
				int x = 0;
				for (Item i1 : i) {
					if ((i1.owner.equals(InMemoryModel.currentUser)) && (i1.type.equals(type1)) && (i1.status == status1)) {
						retVal[x++] = i1.name;
					}
				}
				return retVal;
	}
	//return after date given
	/**
	 * Filters a list by date
	 * @param type1 is if lost or found
	 * @param date1 is the date we want to filter after
	 * @return names of all the filtered items
	 */
	public String[] filterByDate(String type1, Date date1) {
		//Making a copy of data to pass over trust boundary
				Collection<Item> i = items.values();
				int size = 0;
				for (Item i1 : i) {
					if ((i1.owner.equals(InMemoryModel.currentUser)) && (i1.type.equals(type1)) && (i1.date.compareTo(date1)>0)) {
						size++;
					}
				}
				String[] retVal = new String[size];
				int x = 0;
				for (Item i1 : i) {
					if ((i1.owner.equals(InMemoryModel.currentUser)) && (i1.type.equals(type1)) && (i1.date.compareTo(date1)>0)) {
						retVal[x++] = i1.name;
					}
				}
				return retVal;
	}
	
	
	
	/*public Item[] getItems() {
	//Making a copy of data to pass over trust boundary
	Collection<Item> i = items.values();
	Item[] retVal = new Item[i.size()];
	int x = 0;
	for (Item i1 : i) {
		if (i1.owner.equals(InMemoryModel.currentUser)) {
			retVal[x++] = i1;
		}
	}
	return retVal;
}*/
	
}